/*
 *  DialogTree.cpp
 *  SquirrelAdven
 *
 *  Created by Wen Xu on 3/7/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#include "DialogTree.h"
#include <fstream>
#include <iostream>
#include <sstream>

DialogTree::DialogTree(string filename) {
	root = NULL;
	this->filename = filename;
	parseData();
}

DialogTree::~DialogTree() {
}

void DialogTree::parseData() {
	ifstream i_file;
	i_file.open(filename.c_str());
	
	string str;
	char *token;
	while (getline(i_file, str)) {
		// Dialog
		if (str.find(":Dialog") != -1) {
			// DEBUG
			cout << "find Dialog data\n";
			// Read each NPC data block
			DialogNode * node;
			
			while (getline(i_file, str) && str.find(":") == -1){
				if (str[str.length()-1] == '\r') // there is a \r in my line!
					str.erase(str.length()-1); // throw it away
				// BEGIN
				if (str.find("begin") != -1) {
					node= new DialogNode;
					continue;
				}
				// ID
				if (str.find("ID") != -1) {
					int begin_index = str.find("ID")+strlen("ID");
					str = str.substr(begin_index, str.length()-begin_index);
					// convert to int
					node->setDialogID(atoi(str.c_str()));
					continue;
				}
				
				// TYPE
				if (str.find("Type") != -1) {
					int begin_index = str.find("Type")+strlen("Type");
					str = str.substr(begin_index, str.length()-begin_index);
					// convert to int
					node->setDialogType(atoi(str.c_str()));
					continue;
				}
				
				// CONTENT
				if (str.find("Content") != -1) {
					int begin_index = str.find("Content")+strlen("Content")+1;
					str = str.substr(begin_index, str.length()-begin_index);
					node->setDialogContent(str);
					continue;
				}
				
				// POINTS
				if (str.find("Points") != -1) {
					int begin_index = str.find("Points")+strlen("Points");
					str = str.substr(begin_index, str.length()-begin_index);
					// convert to int
					node->setDialogPoints(atoi(str.c_str()));
					continue;
				}
				
				// END
				if (str.find("end") != -1) {
					//node->printData();
					nodeList.push_back(*node);
					continue;
				}
			};
			
		}
		
		if (str.find(":Hierarchy") != -1) {
			// DEBUG
			std::cout << "find Hierarchy data\n";
			
			while (getline(i_file, str) && str.find(":") == -1){
				if (str[str.length()-1] == '\r') // there is a \r in my line!
					str.erase(str.length()-1); // throw it away
				
				// create dialog tree
				int baseID, childID;
				
				int i = 0;
				token = strtok((char*)str.c_str(), " ");
				while (token != NULL) {
					if (i == 0) {
						baseID = atoi(token);
						
						//DEBUG
						std::cout << baseID << " ";
					}
					else {
						childID = atoi(token);
						DialogNode * baseNode, * childNode;
						baseNode = getDialogNodeByID(baseID);
						childNode = getDialogNodeByID(childID);
						baseNode->addChild(childNode);
						
						//DEBUG
						std::cout << childID << " ";
					}
					token = strtok(NULL, " ");
					i++;
				}
				
				//DEBUG
				std::cout << "\n";
			}				
			
		}
	}
	i_file.close();
}

DialogNode * DialogTree::getRoot() {
	root = getDialogNodeByID(1);
	return root;
}

string DialogTree::getCurrentDialogText(DialogNode * cur) {	
	if (!cur) {
		return "";
	}
	// non-question
	if (cur->getDialogType() == 0) {
		return cur->getDialogContent();
	}
	// question
	else if (cur->getDialogType() == 1) {
		string res = cur->getDialogContent() + " Options: ";
		int i;
		for (i = 0; i < cur->getChildrenCount(); i++) {
			std::ostringstream ss; 
			ss << (i+1); 
			res += ss.str();
			res += ": " + cur->getChildByIndex(i)->getDialogContent() + "     ";
		}
		return res;
	}
	// option
	else if (cur->getDialogType() == 2) {
		return "";
	}
}

DialogNode * DialogTree::getDialogNodeByID(int ID) {
	int i;
	for (i = 0; i < nodeList.size(); i++) {
		if (nodeList[i].getDialogID() == ID) {
			return &nodeList[i];
		}
	}
	return NULL;
}

int DialogTree::getLastDialogID() {
	int index = nodeList.size() - 1;
	return nodeList[index].getDialogID();
}

void DialogTree::printData() {
	root = getDialogNodeByID(1);
	printData(root);
}

void DialogTree::printData(DialogNode * cur) {
	if (cur == NULL) {
		return ;
	}
	cur->printData();
	for (int i = 0; i < cur->getChildrenCount(); i++) {
		printData(cur->getChildByIndex(i));
	}
}

DialogNode * DialogTree::getNextDialogNode(DialogNode * cur, int option) {
	int n = cur->getChildrenCount();
	if (n == 1) {
		return cur->getChildByIndex(0);
	}
	else {
		if (option > 0 && option <= cur->getChildrenCount()) {
			return cur->getChildByIndex(option - 1);
		}
		else {
			return cur->getChildByIndex(0);
		}

	}

}

